/***************************************************************************
* Lyrics-Player                                                            *
* Copyright (C) 2012 Andrey Derevyanko <derandr@gmail.com>                 *
*                                                                          *
* This program is free software: you can redistribute it and/or modify     *
* it under the terms of the GNU General Public License as published by     *
* the Free Software Foundation, either version 3 of the License, or        *
* (at your option) any later version.                                      *
*                                                                          *
* This program is distributed in the hope that it will be useful,          *
* but WITHOUT ANY WARRANTY; without even the implied warranty of           *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
* GNU General Public License for more details.                             *
*                                                                          *
* You should have received a copy of the GNU General Public License        *
* along with this program.  If not, see <http://www.gnu.org/licenses/>.    *
***************************************************************************/

/*! \file trackRecModel.cpp
 *  \brief Implementation of tacks data model
 *  \author Andrey Derevyanko <derandr@gmail.com>
 *  \version 1.1
 *  \date 10/10/2012
 *  \copyright GNU Public License
 */

#include "trackRecModel.h"

TrackRecordModel::TrackRecordModel()
{
    //lpVersion::setPhononVersion(Phonon::phononVersion());
    //lpVersion::setProgramVersion("0.2.1");
    playMedia = new Phonon::MediaObject;
    playMedia->setTickInterval(1000);
    metaDataReader = new id3Lib::id3Reader;
    metaDataWriter = new id3Lib::id3Writer;
    isRandomPlay = false;
    isPaused = false;
    connect(&nameThread, SIGNAL(updateModel()), SLOT(updateMe()));
    connect(playMedia, SIGNAL(finished()), SLOT(playNextTrack()));
    connect(playMedia, SIGNAL(totalTimeChanged(qint64)), SLOT(getTotalTime(qint64)));
    connect(playMedia, SIGNAL(tick(qint64)), SLOT(getCurrentTime(qint64)));
    connect(playMedia, SIGNAL(metaDataChanged()), SLOT(trackDataReady()));
    connect(&mDataProcTimer, SIGNAL(timeout()), SLOT(trackDataTimeOut()));
    connect(this, SIGNAL(newFileName(QString)), metaDataReader, SLOT(newSourceFile(QString)));
    connect(metaDataReader, SIGNAL(newMetaData(trackMetaData_t)), SLOT(trackID3DataReady(trackMetaData_t)));
    connect(this, SIGNAL(newMetaDataToSave(QString,trackMetaData_t)), metaDataWriter, SLOT(setMetaData(QString,trackMetaData_t)));

    nameThread.setData(&trackList);
    nameThread.start();
}

TrackRecordModel::~TrackRecordModel()
{
}

QVariant TrackRecordModel::data(const QModelIndex &index, int role) const
{
    if (!index.isValid()) return QVariant();
    if (role == Qt::DisplayRole)
        return (trackList[index.row()].isProcessed) ? trackList[index.row()].trackName : trackList[index.row()].filePath;
    if (role == Qt::BackgroundRole)
    {
        if (index.row() == selectRow) return Qt::darkGreen;
        if (index.row() == playRow) return Qt::darkCyan;
    }
    if (role == Qt::TextColorRole)
    {
        if (index.row() == selectRow) return Qt::white;
        if (index.row() == playRow) return Qt::white;
    }
    return QVariant();
}

int TrackRecordModel::rowCount(const QModelIndex &parent/* = QModelIndex()*/) const
{
    (void)parent;
    return trackList.count();
}

QVariant TrackRecordModel::headerData(int section, Qt::Orientation orientation, int role) const
{
    if (!role == Qt::DisplayRole) return QVariant();
    return (orientation == Qt::Horizontal) ? "Name" : QString::number(section+1);
}

Phonon::MediaObject * TrackRecordModel::mediaObject()
{
    return playMedia;
}

int TrackRecordModel::addTrack(QString sFilePath)
{
    trackList.append(trackRecord(sFilePath));
    nameThread.metaDataProcess();
    reset();
    return trackList.count();
}

void TrackRecordModel::fileSelect(const QModelIndex & index)
{
    QString textFileString;
    selectRow = index.row();
    textFileString = trackList[selectRow].filePath;
    textFileString.insert(textFileString.lastIndexOf('/')+1, "Text/");
    textFileString.replace(textFileString.lastIndexOf('.')+1, 5, "txt");
    emit lyricsAvailable(textFileString);
    reset();
}

void TrackRecordModel::playThis()
{
    playRow = selectRow;
    reset();
    ssPlay();
}

void TrackRecordModel::ssPlay()
{
    if (!isPaused)
    {
        emit newTrackName((trackList[playRow].isProcessed) ? trackList[playRow].trackName : trackList[playRow].filePath);
        emit newFileName(trackList[playRow].filePath);
        mDataProcTimer.start(processThread::max_proc_time);
        playMedia->setCurrentSource(Phonon::MediaSource(trackList[playRow].filePath));
        trackMetaData.m_filePath = trackList[playRow].filePath;
    }
    playMedia->play();
    isPaused = false;
    emit newPlayIcon(st_Play);
}

void TrackRecordModel::ssPause()
{
    playMedia->pause();
    isPaused = true;
    emit newPlayIcon(st_Pause);
}

void TrackRecordModel::ssStop()
{
    playMedia->stop();
    isPaused = false;
    emit newPlayIcon(st_Stop);
}

void TrackRecordModel::saveModel(QString fileName/* = "default.spl"*/)
{
    QFile listFile;
    if (fileName == "default.spl") listFile.setFileName(QDir::currentPath()+"/default.spl");
    else listFile.setFileName(fileName);
    QTextStream listTextStream(&listFile);
    listFile.open(QIODevice::WriteOnly | QIODevice::Text);
    for (int fpI = 0; fpI < trackList.count(); fpI++)
    listTextStream<<trackList[fpI].filePath<<"\n"<<trackList[fpI].trackName<<"\n"<<trackList[fpI].isProcessed<<"\n";
    listFile.close();
}

void TrackRecordModel::loadModel(QString fileName/* = "default.spl"*/)
{
    QFile listFile;
    if (fileName == "default.spl") listFile.setFileName(QDir::currentPath()+"/default.spl");
    else listFile.setFileName(fileName);
    QString fileNameLine, trackNameLine, processedLine;
    QTextStream listTextStream(&listFile);
    trackList.clear();
    listFile.open(QIODevice::ReadOnly | QIODevice::Text);
    fileNameLine = listTextStream.readLine();
    trackNameLine = listTextStream.readLine();
    processedLine = listTextStream.readLine();
    while (!fileNameLine.isNull())
    {
        trackList.append(trackRecord(fileNameLine, trackNameLine, (processedLine == "1")));
        fileNameLine = listTextStream.readLine();
        trackNameLine = listTextStream.readLine();
        processedLine = listTextStream.readLine();
    }
    listFile.close();
    reset();
    ssStop();
    nameThread.metaDataProcess();
}

void TrackRecordModel::updateMe()
{
    reset();
}

void TrackRecordModel::fileRemove()
{
    trackList.removeAt(selectRow);
    reset();
}

void TrackRecordModel::clearList()
{
    playRow = 0;
    selectRow = 0;
    trackList.clear();
    reset();
}

void TrackRecordModel::playLast()
{
    this->newTrack2Play(lastTrack);
}

void TrackRecordModel::playFirst()
{
    newTrack2Play(firstTrack);
}


void TrackRecordModel::playPrevTrack()
{
    if (isRandomPlay) newTrack2Play(randTrack);
        else newTrack2Play(prevTrack);
}

void TrackRecordModel::playNextTrack()
{
    if (isRandomPlay) newTrack2Play(randTrack);
        else newTrack2Play(nextTrack);
}

void TrackRecordModel::newTrack2Play(gotoTrack t_goto)
{
    switch (t_goto)
    {
    case firstTrack: playRow = 0; break;
    case lastTrack: playRow = trackList.count()-1; break;
    case nextTrack: playRow++; break;
    case prevTrack: playRow--; break;
    case randTrack: qsrand(QTime::currentTime().msec()); playRow = qrand()%trackList.count(); break;
    }
    if (playRow>=trackList.count())
    {
        ssStop();
        return;
    }
    QString textFileString;
    textFileString = trackList[playRow].filePath;
    textFileString.insert(textFileString.lastIndexOf('/')+1, "Text/");
    textFileString.replace(textFileString.lastIndexOf('.')+1, 5, "txt");
    emit lyricsAvailable(textFileString);
    reset();
    if (t_goto == firstTrack) return;
    this->ssPlay();
}

void TrackRecordModel::getTotalTime(qint64 t_Time)
{
    emit newTotalTime(t_Time);
}

void TrackRecordModel::getCurrentTime(qint64 t_Time)
{
    emit newCurrentTime(t_Time);
}

void TrackRecordModel::trackDataReady()
{
    mDataProcTimer.stop();
//    QMultiMap<QString, QString> metaDataMMap = playMedia->metaData();
//    trackMetaData.m_artist = metaDataMMap.value("ARTIST", "-");
//    trackMetaData.m_title = metaDataMMap.value("TITLE", "-");
//    trackMetaData.m_album = metaDataMMap.value("ALBUM", "-");
//    trackMetaData.m_year = metaDataMMap.value("DATE", "-");
//    trackMetaData.m_genre = metaDataMMap.value("GENRE", "-");
//    emit newFileInfo(trackMetaData);
}

void  TrackRecordModel::trackID3DataReady(trackMetaData_t data)
{
    emit newFileInfo(data);
}

void TrackRecordModel::trackDataTimeOut()
{
    mDataProcTimer.stop();
    trackMetaData.m_artist = "-";
    trackMetaData.m_title = "-";
    trackMetaData.m_album = "-";
    trackMetaData.m_year = "-";
    trackMetaData.m_genre = "-";
    emit newTrackName(tr("File format not supported"));
    emit newFileInfo(trackMetaData);
    newTrack2Play(nextTrack);
}

void TrackRecordModel::newEditedMetaData(trackMetaData_t data)
{
    ssStop();
    playMedia->clear();
    emit newMetaDataToSave(trackList[playRow].filePath, data);
}

bool TrackRecordModel::getRandomPlay()
{
    return isRandomPlay;
}


void TrackRecordModel::setRandomPlay(bool bRnd)
{
    isRandomPlay = bRnd;
}
